package com.ccsu.joysport.service;


import ch.qos.logback.core.util.StringUtil;
import com.ccsu.joysport.controller.model.resp.ActivityEntry;
import com.ccsu.joysport.controller.model.resp.ActivityResp;
import com.ccsu.joysport.dto.*;
import com.ccsu.joysport.entity.Activity;
import com.ccsu.joysport.entity.Club;
import com.ccsu.joysport.entity.StudentActivity;
import com.ccsu.joysport.repository.ActivityRepository;
import com.ccsu.joysport.repository.ClubRepository;
import com.ccsu.joysport.repository.StudentActivityRepository;
import com.ccsu.joysport.util.JwtUtil;
import io.jsonwebtoken.JwtException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.web.server.ResponseStatusException;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class ActivityService {

    @Autowired
    private ActivityRepository activityRepository;

    @Autowired
    private ClubRepository clubRepository;
    @Autowired
    private JwtUtil jwtUtil;
//    public Activity getActivityDetail(String activityId) {
//
//        return activityRepository.findByActivityId(activityId)
//                .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "未找到活动"));
//    }
    public StudentActivity getStudentActivityDetail(String token,String activityId) {
        String StuId= jwtUtil.extractId(token);

        return studentActivityRepository.findByActivityIdAndStudentId(activityId,StuId)
                .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "未找到报名信息"));
    }
    public FormattedActivityResponse getActivityDetail(String token, String activityId) {

        String stuId;
        try {
            stuId = jwtUtil.extractId(token);
        } catch (JwtException e) {
            throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "token解析失败");
        }

        Activity activity = activityRepository.findByActivityId(activityId)
                .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "活动未找到"));

        // 新增过滤逻辑：如果活动状态不是 "approve"，抛出异常
        if (!"approve".equals(activity.getActivityStatus())) {
            throw new ResponseStatusException(HttpStatus.FORBIDDEN, "活动未被批准");
        }
        // 格式化时间字段
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String activityTimeStartFormatted = dateFormat.format(activity.getActivityTimeStart());
        String activityTimeEndFormatted = dateFormat.format(activity.getActivityTimeEnd());

        // 获取报名状态
        StudentActivity studentActivity;
        String activityStatus = "未报名";
        try {
            studentActivity = studentActivityRepository.findByActivityIdAndStudentId(activityId, stuId)
                    .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "未找到报名信息"));
            activityStatus = studentActivity.getActivityState();
        } catch (ResponseStatusException e) {
            // 未找到报名信息时返回默认值或处理逻辑
            studentActivity = null;
        }
        // 获取俱乐部信息并提取学院信息
        Club club = clubRepository.findById(activity.getClubId())
                .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "未找到关联的俱乐部"));
        String college = club.getCollege();

        // 计算剩余可报名人数
        List<StudentActivity> studentActivityList = studentActivityRepository.findByActivityId(activityId);
        int activityMax = activity.getActivityMax();
        long registeredCount = studentActivityList.stream().count();
        int remainingSpots = activityMax - (int) registeredCount;
        boolean canRegister = remainingSpots > 0;

        // 创建并返回响应对象
        FormattedActivityResponse response = new FormattedActivityResponse(
                activity.getActivityId(),
                activity.getActivityName(),
                activity.getActivityDesc(),
                activity.getActivityImage(),
                activityTimeStartFormatted,
                activityTimeEndFormatted,
                remainingSpots,
                activity.getActivityOrganizer(),
                activity.getClubId(),
                activity.getActivityPerson(),
                activity.getActivityPlace(),
                activityStatus,
                college
        );

        return response;
    }



    @Autowired
    private StudentActivityRepository studentActivityRepository;

    public SignupActivityResponse signupActivity(SignupActivityRequest request) {

        String StuId;
        try {
            StuId = jwtUtil.extractId(request.getToken());
        } catch (JwtException e) {
            return new SignupActivityResponse("failed", "token解析失败");
        }
        // 检查是否已经报名过这个活动
        if (studentActivityRepository.findByActivityIdAndStudentId(request.getActivityId(), StuId).isPresent()) {
            return new SignupActivityResponse("failed", "已经报名，请不要重复报名");
        }

        // 从 activity 表中获取活动名称
        Activity activity = activityRepository.findById(request.getActivityId())
                .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "活动未找到"));
        // 获取服务器当前时间
        Timestamp currentTime = Timestamp.from(Instant.now());

        // 检查当前时间是否在活动开始时间之前
        if (currentTime.after(activity.getActivityTimeEnd())) {
            return new SignupActivityResponse("fail", "活动已结束，无法报名");
        }
        // 创建新的报名记录
        StudentActivity studentActivity = new StudentActivity();
        studentActivity.setStudentId(StuId);
        studentActivity.setActivityId(request.getActivityId());
        studentActivity.setActivityName(activity.getActivityName()); // 从数据库获取活动名称
        studentActivity.setActivityState("N"); // 默认签到状态为N
        studentActivityRepository.save(studentActivity);

        return new SignupActivityResponse("successed", "报名成功");
    }

    public CancelSignupActivityResponse cancelSignupActivity(CancelSignupActivityRequest request) {

        String StuId;
        try {
            StuId = jwtUtil.extractId(request.getToken());
        } catch (JwtException e) {
            return new CancelSignupActivityResponse("fail", "token解析失败");
        }
        Activity activity = activityRepository.findByActivityId(request.getActivityId())
                .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "活动未找到"));

        // 获取服务器当前时间
        Timestamp currentTime = Timestamp.from(Instant.now());

        // 检查当前时间是否在活动开始时间之前
        if (currentTime.after(activity.getActivityTimeStart())) {
            return new CancelSignupActivityResponse("fail", "活动已开始，无法取消报名");
        }


        StudentActivity studentActivity = studentActivityRepository.findByActivityIdAndStudentId(request.getActivityId(), StuId)
                .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "报名记录未找到"));

        studentActivityRepository.delete(studentActivity);
        return new CancelSignupActivityResponse("success", "取消报名成功");
    }


    public List<JoinedActivitiesResponse> getJoinedActivities(String token) {
        String StuId = jwtUtil.extractId(token);
        if (StuId == null || StuId.isEmpty()) {
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "无效的token");
        }

        if (!studentActivityRepository.existsByStudentId(StuId)) {
            throw new ResponseStatusException(HttpStatus.NOT_FOUND, "学生未找到");
        }

        List<StudentActivity> studentActivities = studentActivityRepository.findByStudentId(StuId);
        if (studentActivities.isEmpty()) {
            throw new ResponseStatusException(HttpStatus.NOT_FOUND, "学生未参加任何活动");
        }

        List<String> activityIds = studentActivities.stream().map(StudentActivity::getActivityId).collect(Collectors.toList());
        List<Activity> activities = activityRepository.findAllById(activityIds);
        // 获取每个活动的报名人数
        List<StudentActivity> studentActivityList = studentActivityRepository.findByActivityIdIn(activityIds);
        Map<String, Long> activityIdAndCountMap = studentActivityList.stream()
                .collect(Collectors.groupingBy(StudentActivity::getActivityId, Collectors.counting()));

        List<JoinedActivitiesResponse> responses = activities.stream().map(activity -> {
            JoinedActivitiesResponse response = new JoinedActivitiesResponse();
            response.setActivityId(activity.getActivityId());
            response.setActivityName(activity.getActivityName());
            response.setActivityDesc(activity.getActivityDesc());
            response.setActivityImage(activity.getActivityImage());
            response.setActivityMax(activity.getActivityMax());
            response.setActivityOrganizer(activity.getActivityOrganizer());
            response.setClubId(activity.getClubId());
            response.setActivityPerson(activity.getActivityPerson());
            response.setActivityPlace(activity.getActivityPlace());
            response.setActivityTimeStart(activity.getActivityTimeStart());
            response.setActivityTimeEnd(activity.getActivityTimeEnd());
            LocalDateTime now = LocalDateTime.now();
            int activityMax = activity.getActivityMax();
            long registeredCount = activityIdAndCountMap.getOrDefault(activity.getActivityId(), 0L);
            response.setActivityMax(activityMax - (int) registeredCount);
            if(response.getActivityMax() <= 0){
                response.setActivityStatus("报名人数已满");
            }
            // 设置活动状态
            if (activity.getActivityTimeStart() != null && activity.getActivityTimeEnd() != null) {
                LocalDateTime startTime = activity.getActivityTimeStart().toLocalDateTime();
                LocalDateTime endTime = activity.getActivityTimeEnd().toLocalDateTime();

                if (now.isBefore(startTime)) {
                    response.setActivityStatus("报名中");
                } else if (now.isAfter(endTime)) {
                    response.setActivityStatus("已结束");
                } else {
                    response.setActivityStatus("进行中");
                }
            }
            Club club = clubRepository.findById(activity.getClubId()) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "未找到关联的俱乐部"));
            response.setCollege(club.getCollege());
            return response;
        }).collect(Collectors.toList());

        return responses;
    }



    public List<ActivityWithClubResponse> searchActivities(String queryText) {
        List<Activity> activities = activityRepository.findByActivityNameContainingIgnoreCase(queryText);

        // 过滤活动状态为 "approve"
        activities = activities.stream()
                .filter(activity -> "approve".equals(activity.getActivityStatus()))
                .collect(Collectors.toList());

        // 获取每个活动的ID
        List<String> activityIds = activities.stream().map(Activity::getActivityId).collect(Collectors.toList());

        // 查询每个活动的报名人数
        List<StudentActivity> studentActivityList = studentActivityRepository.findByActivityIdIn(activityIds);
        Map<String, Long> activityIdAndCountMap = studentActivityList.stream()
                .collect(Collectors.groupingBy(StudentActivity::getActivityId, Collectors.counting()));

        List<ActivityWithClubResponse> responses = activities.stream().map(activity -> {
            Club club = clubRepository.findById(activity.getClubId())
                    .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "未找到关联的俱乐部"));
            // 计算剩余可报名人数
            int activityMax = activity.getActivityMax();
            long registeredCount = activityIdAndCountMap.getOrDefault(activity.getActivityId(), 0L);
            int remainingSpots = activityMax - (int) registeredCount;



            return new ActivityWithClubResponse(
                    activity.getActivityId(),
                    activity.getActivityName(),
                    activity.getActivityDesc(),
                    activity.getActivityImage(),
                    activity.getActivityTimeStart().toString(),
                    activity.getActivityTimeEnd().toString(),
                    remainingSpots,
                    activity.getActivityOrganizer(),
                    activity.getClubId(),
                    activity.getActivityPerson(),
                    activity.getActivityPlace(),
                    club.getCollege(),
                    club.getClubName()
            );
        }).collect(Collectors.toList());

        return responses;
    }




    public ActivityResp activityPage(String searchText, Integer pageNum, Integer pageSize) {

        Page<Activity> all;

        if (StringUtil.notNullNorEmpty(searchText)) {
            searchText = "%" + searchText + "%";
            all = activityRepository.findByActivityNameLike(searchText, PageRequest.of(pageNum, pageSize));
        } else {
            all = activityRepository.findAll(PageRequest.of(pageNum, pageSize));
        }

        List<String> clubIds = all.getContent().stream().map(Activity::getClubId).collect(Collectors.toList());

        List<Club> clubList = clubRepository.findByClubIdIn(clubIds);

        Map<String, String> clubIdAndCollegeMap = clubList.stream().collect(Collectors.toMap(Club::getClubId, Club::getCollege));

        // 获取每个活动的ID
        List<String> activityIds = all.getContent().stream().map(Activity::getActivityId).collect(Collectors.toList());

// 查询每个活动的报名人数
        List<StudentActivity> studentActivityList = studentActivityRepository.findByActivityIdIn(activityIds);

// 构建活动ID与报名人数的映射
        Map<String, Long> activityIdAndCountMap = studentActivityList.stream()
                .collect(Collectors.groupingBy(StudentActivity::getActivityId, Collectors.counting()));

        List<ActivityEntry> list = all.getContent().stream()
                // 过滤活动状态为 "approve"
                .filter(activity -> "approve".equals(activity.getActivityStatus()))
                .map(activityDB -> {
            ActivityEntry activityEntry = new ActivityEntry();
            Timestamp currentTime = new Timestamp(System.currentTimeMillis());

            BeanUtils.copyProperties(activityDB, activityEntry);
            activityEntry.setCollege(clubIdAndCollegeMap.get(activityDB.getClubId()));
            activityEntry.setActivityTimeStart(getFormatted(activityDB.getActivityTimeStart()));
            activityEntry.setActivityTimeEnd(getFormatted(activityDB.getActivityTimeEnd()));

            // 计算剩余可报名人数
            int activityMax = activityDB.getActivityMax();
            long registeredCount = activityIdAndCountMap.getOrDefault(activityDB.getActivityId(), 0L);
            activityEntry.setActivityMax(activityMax - (int) registeredCount);
            if(activityEntry.getActivityMax() <= 0){
                activityEntry.setActivityStatus("报名人数已满");
            }
            else if (currentTime.after(Timestamp.valueOf(activityEntry.getActivityTimeStart()))&&currentTime.before(Timestamp.valueOf(activityEntry.getActivityTimeEnd()))) {

                activityEntry.setActivityStatus("进行中");
            }
            else if (currentTime.after(Timestamp.valueOf(activityEntry.getActivityTimeEnd()))){

                activityEntry.setActivityStatus("已结束");
            }
            else if (currentTime.before(Timestamp.valueOf(activityEntry.getActivityTimeStart()))){

                activityEntry.setActivityStatus("报名中");
            }


            return activityEntry;
        }).collect(Collectors.toList());

        ActivityResp activityResp = new ActivityResp();
        activityResp.setList(list);
        activityResp.setTotalCount((int) all.getTotalElements());
        return activityResp;
    }



    private String getFormatted(Timestamp timestamp) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return dateFormat.format(timestamp);
    }

}
